﻿#region

using System;
using System.Collections.Generic;
using MediaSage.Lib.Utilities;
using NHibernate;
using NHibernate.Criterion;

#endregion

namespace MediaSage.Lib.Database
{
    public class VideoEntity : DatabaseObject
    {
        #region Constructors

        public VideoEntity()
        {
            AltNames = new List<string>();
            Distributors = new List<string>();
            Episodes = new List<EpisodeEntity>();
            SeriesAirsDaysOfWeek = new List<DayOfWeek?>();
            Languages = new List<string>();
            Categories = new List<string>();
            Studios = new List<string>();
            Countries = new List<string>();
            Images = new List<ImageEntity>();
            Cast = new List<PersonEntity>();
            Metadata = new List<MetadataEntity>();
            Genre = new List<string>();
            SimilarItems = new List<SimilarItemEntity>();
            Certifications = new List<CertificationEntity>();
        }

        #endregion Constructors

        #region Properties

        public virtual ImageEntity Backdrop { get; set; }

        public virtual ImageEntity Poster { get; set; }

        public virtual IList<SimilarItemEntity> SimilarItems { get; set; }

        public virtual bool Adult { get; set; }

        public virtual IList<string> AltNames { get; set; }

        public virtual int AudioBitrate { get; set; }

        public virtual int AudioChannels { get; set; }

        public virtual string AudioCodec { get; set; }

        public virtual string AudioCodecRaw { get; set; }

        public virtual long AudioFrequency { get; set; }

        public virtual bool AudioSAP { get; set; }

        public virtual string Budget { get; set; }

        public virtual IList<PersonEntity> Cast { get; set; }

        public virtual IList<string> Categories { get; set; }

        public virtual IList<CertificationEntity> Certifications { get; set; }

        public virtual bool ContentProtected { get; set; }

        public virtual IList<string> Countries { get; set; }

        public virtual string Description { get; set; }

        public virtual IList<string> Distributors { get; set; }

        public virtual string DVDId { get; set; }

        public virtual IList<EpisodeEntity> Episodes { get; set; }

        public virtual string Filename { get; set; }

        public virtual long FileSize { get; set; }

        public virtual IList<string> Genre { get; set; }

        public virtual Guid ID { get; protected set; }

        public virtual IList<ImageEntity> Images { get; set; }

        public virtual string IMDBID { get; set; }

        public virtual bool IsDelay { get; set; }

        public virtual bool IsFinale { get; set; }

        public virtual bool IsHDContent { get; set; }

        public virtual bool IsLive { get; set; }

        public virtual bool IsMovie { get; set; }

        public virtual bool isPremire { get; set; }

        public virtual bool IsRepeat { get; set; }

        public virtual bool IsSAP { get; set; }

        public virtual bool IsSport { get; set; }

        public virtual bool isSubtitled { get; set; }

        public virtual bool IsTVSeries { get; set; }

        public virtual IList<string> Languages { get; set; }

        public virtual DateTime? LastModified { get; set; }

        public virtual IList<MetadataEntity> Metadata { get; set; }

        public virtual string MPAARating { get; set; }

        public virtual string Name { get; set; }

        public virtual string NetworkAffiliation { get; set; }

        public virtual DateTime? OriginalBroadcastTime { get; set; }

        public virtual string Overview { get; set; }

        public virtual string ParentalRating { get; set; }

        public virtual double Popularity { get; set; }

        public virtual double Rating { get; set; }

        public virtual DateTime? Released { get; set; }

        public virtual string Revenue { get; set; }

        public virtual int RottenTomatosID { get; set; }

        public virtual TimeSpan RunTime { get; set; }

        public virtual double Score { get; set; }

        public virtual IList<DayOfWeek?> SeriesAirsDaysOfWeek { get; set; }

        public virtual DateTime? SeriesAirsTime { get; set; }

        public virtual int SeriesID { get; set; }

        public virtual string StationName { get; set; }

        public virtual IList<string> Studios { get; set; }

        public virtual string Subtitle { get; set; }

        public virtual int TmdbID { get; set; }

        public virtual string Trailer { get; set; }

        public virtual bool Translated { get; set; }

        public virtual int TvdbID { get; set; }

        public virtual string URL { get; set; }

        public virtual string VideoAspect { get; set; }

        public virtual float VideoBitrate { get; set; }

        public virtual string VideoBitRateMode { get; set; }

        public virtual string VideoCodec { get; set; }

        public virtual string VideoCodecVersion { get; set; }

        public virtual long VideoFilesize { get; set; }

        public virtual float VideoFrameRate { get; set; }

        public virtual int VideoHeight { get; set; }

        public virtual TimeSpan VideoLength { get; set; }

        public virtual string VideoQuality { get; set; }

        public virtual int VideoWidth { get; set; }

        #endregion Properties

        public override void Save()
        {
            ISession session = DBUtil.GetSession();
            LastModified = DateTime.Now;
            using (session.BeginTransaction())
            {
                Disjunction disj = Restrictions.Disjunction();
                if (TmdbID != 0)
                {
                    disj.Add(Restrictions.Eq("TmdbID", TmdbID));
                }
                if (IMDBID != null && IMDBID.Length > 0)
                {
                    disj.Add(Restrictions.Eq("IMDBID", IMDBID));
                }
                if (TvdbID != 0)
                {
                    disj.Add(Restrictions.Eq("TvdbID", TvdbID));
                }
                var dbVE = session.CreateCriteria(typeof(VideoEntity)).Add(disj).UniqueResult<VideoEntity>();
                if (dbVE != null)
                {
                    ID = dbVE.ID;
                    var MergedObject = new VideoEntity();
                    MergedObject.Adult = (bool)Util.CopyObject(Adult, dbVE.Adult, config.MergeType);
                    MergedObject.AudioBitrate = (int)Util.CopyObject(AudioBitrate, dbVE.AudioBitrate, config.MergeType);
                    MergedObject.AudioChannels =
                        (int)Util.CopyObject(AudioChannels, dbVE.AudioChannels, config.MergeType);
                    MergedObject.AudioCodec = (string)Util.CopyObject(AudioCodec, dbVE.AudioCodec, config.MergeType);
                    MergedObject.AudioCodecRaw =
                        (string)Util.CopyObject(AudioCodecRaw, dbVE.AudioCodecRaw, config.MergeType);
                    MergedObject.AudioFrequency =
                        (long)Util.CopyObject(AudioFrequency, dbVE.AudioFrequency, config.MergeType);
                    MergedObject.Budget = (string)Util.CopyObject(Budget, dbVE.Budget, config.MergeType);

                    MergedObject.Cast = MediaUtil.MergePersonList(Cast, dbVE.Cast, config.MergeType,
                                                                  config.MergeOnPersonName);
                    MergedObject.Categories =
                        (List<String>)Util.CopyObject(Categories, dbVE.Categories, config.MergeType);
                    MergedObject.Certifications =
                        MediaUtil.MergeCertifications(Certifications, dbVE.Certifications, config.MergeType);
                    MergedObject.ContentProtected =
                        (bool)Util.CopyObject(ContentProtected, dbVE.ContentProtected, config.MergeType);
                    MergedObject.Countries = (List<string>)Util.CopyObject(Countries, dbVE.Countries, config.MergeType);
                    MergedObject.Description = (string)Util.CopyObject(Description, dbVE.Description, config.MergeType);
                    MergedObject.Distributors =
                        (List<string>)Util.CopyObject(Distributors, dbVE.Distributors, config.MergeType);
                    MergedObject.Episodes = MediaUtil.MergeEpisodeList(Episodes, dbVE.Episodes, config.MergeType,
                                                                       config.MergeOnPersonName);
                    MergedObject.Filename = (string)Util.CopyObject(Filename, dbVE.Filename, config.MergeType);
                    MergedObject.Genre = (List<string>)Util.CopyObject(Genre, dbVE.Genre, config.MergeType);
                    MergedObject.Backdrop = MediaUtil.MergeImageEntity(Backdrop, dbVE.Backdrop, config.MergeType);
                    MergedObject.Poster = MediaUtil.MergeImageEntity(Poster, dbVE.Poster, config.MergeType);
                    MergedObject.Images = MediaUtil.MergeImageList(Images, dbVE.Images, config.MergeType);
                    MergedObject.IMDBID = (string)Util.CopyObject(IMDBID, dbVE.IMDBID, config.MergeType);
                    MergedObject.IsDelay = (bool)Util.CopyObject(IsDelay, dbVE.IsDelay, config.MergeType);
                    MergedObject.IsFinale = (bool)Util.CopyObject(IsFinale, dbVE.IsFinale, config.MergeType);
                    MergedObject.IsHDContent = (bool)Util.CopyObject(IsHDContent, dbVE.IsHDContent, config.MergeType);
                    MergedObject.IsLive = (bool)Util.CopyObject(IsLive, dbVE.IsLive, config.MergeType);
                    MergedObject.IsMovie = (bool)Util.CopyObject(IsMovie, dbVE.IsMovie, config.MergeType);
                    MergedObject.isPremire = (bool)Util.CopyObject(isPremire, dbVE.isPremire, config.MergeType);
                    MergedObject.IsRepeat = (bool)Util.CopyObject(IsRepeat, dbVE.IsRepeat, config.MergeType);
                    MergedObject.IsSAP = (bool)Util.CopyObject(IsSAP, dbVE.IsSAP, config.MergeType);
                    MergedObject.IsSport = (bool)Util.CopyObject(IsSport, dbVE.IsSport, config.MergeType);
                    MergedObject.isSubtitled = (bool)Util.CopyObject(isSubtitled, dbVE.isSubtitled, config.MergeType);
                    MergedObject.IsTVSeries = (bool)Util.CopyObject(IsTVSeries, dbVE.IsTVSeries, config.MergeType);
                    MergedObject.Languages = (List<string>)Util.CopyObject(Languages, dbVE.Languages, config.MergeType);
                    MergedObject.LastModified =
                        (DateTime?)Util.CopyObject(LastModified, dbVE.LastModified, config.MergeType);
                    MergedObject.Metadata = MediaUtil.MergeMetadataList(Metadata, dbVE.Metadata, config.MergeType);
                    MergedObject.MPAARating = (string)Util.CopyObject(MPAARating, dbVE.MPAARating, config.MergeType);
                    MergedObject.Name = (string)Util.CopyObject(Name, dbVE.Name, config.MergeType);
                    MergedObject.NetworkAffiliation =
                        (string)Util.CopyObject(NetworkAffiliation, dbVE.NetworkAffiliation, config.MergeType);
                    MergedObject.OriginalBroadcastTime =
                        (DateTime?)Util.CopyObject(OriginalBroadcastTime, dbVE.OriginalBroadcastTime, config.MergeType);
                    MergedObject.Overview = (string)Util.CopyObject(Overview, dbVE.Overview, config.MergeType);
                    MergedObject.ParentalRating =
                        (string)Util.CopyObject(ParentalRating, dbVE.ParentalRating, config.MergeType);
                    MergedObject.Popularity = (double)Util.CopyObject(Popularity, dbVE.Popularity, config.MergeType);
                    MergedObject.Rating = (double)Util.CopyObject(Rating, dbVE.Rating, config.MergeType);
                    MergedObject.Released = (DateTime?)Util.CopyObject(Released, dbVE.Released, config.MergeType);
                    MergedObject.Revenue = (string)Util.CopyObject(Revenue, dbVE.Revenue, config.MergeType);
                    MergedObject.RottenTomatosID =
                        (int)Util.CopyObject(RottenTomatosID, dbVE.RottenTomatosID, config.MergeType);
                    MergedObject.RunTime = (TimeSpan)Util.CopyObject(RunTime, dbVE.RunTime, config.MergeType);
                    MergedObject.Score = (double)Util.CopyObject(Score, dbVE.Score, config.MergeType);
                    MergedObject.SeriesAirsDaysOfWeek = MediaUtil.MergeListDayOfWeek(SeriesAirsDaysOfWeek,
                                                                                     dbVE.SeriesAirsDaysOfWeek,
                                                                                     config.MergeType);
                    MergedObject.SeriesAirsTime =
                        (DateTime?)Util.CopyObject(SeriesAirsTime, dbVE.SeriesAirsTime, config.MergeType);
                    MergedObject.SeriesID = (int)Util.CopyObject(SeriesID, dbVE.SeriesID, config.MergeType);
                    MergedObject.StationName = (string)Util.CopyObject(StationName, dbVE.StationName, config.MergeType);
                    MergedObject.Studios = (IList<string>)Util.CopyObject(Studios, dbVE.Studios, config.MergeType);
                    MergedObject.Subtitle = (string)Util.CopyObject(Subtitle, dbVE.Subtitle, config.MergeType);
                    MergedObject.TmdbID = (int)Util.CopyObject(TmdbID, dbVE.TmdbID, config.MergeType);
                    MergedObject.Trailer = (string)Util.CopyObject(Trailer, dbVE.Trailer, config.MergeType);
                    MergedObject.Translated = (bool)Util.CopyObject(Translated, dbVE.Translated, config.MergeType);
                    MergedObject.TvdbID = (int)Util.CopyObject(TvdbID, dbVE.TvdbID, config.MergeType);
                    MergedObject.URL = (string)Util.CopyObject(URL, dbVE.URL, config.MergeType);
                    MergedObject.VideoAspect = (string)Util.CopyObject(VideoAspect, dbVE.VideoAspect, config.MergeType);
                    MergedObject.VideoBitrate =
                        (float)Util.CopyObject(VideoBitrate, dbVE.VideoBitrate, config.MergeType);
                    MergedObject.VideoBitRateMode =
                        (string)Util.CopyObject(VideoBitRateMode, dbVE.VideoBitRateMode, config.MergeType);
                    MergedObject.VideoCodec = (string)Util.CopyObject(VideoCodec, dbVE.VideoCodec, config.MergeType);
                    MergedObject.VideoCodecVersion =
                        (string)Util.CopyObject(VideoCodecVersion, dbVE.VideoCodecVersion, config.MergeType);
                    MergedObject.FileSize = (long)Util.CopyObject(FileSize, dbVE.FileSize, config.MergeType);
                    MergedObject.VideoFrameRate =
                        (float)Util.CopyObject(VideoFrameRate, dbVE.VideoFrameRate, config.MergeType);
                    MergedObject.VideoHeight = (int)Util.CopyObject(VideoHeight, dbVE.VideoHeight, config.MergeType);
                    MergedObject.VideoLength =
                        (TimeSpan)Util.CopyObject(VideoLength, dbVE.VideoLength, config.MergeType);
                    MergedObject.VideoQuality =
                        (string)Util.CopyObject(VideoQuality, dbVE.VideoQuality, config.MergeType);
                    MergedObject.VideoWidth = (int)Util.CopyObject(VideoWidth, dbVE.VideoWidth, config.MergeType);
                }
            }
            base.Save();
        }

        public override void SaveOrUpdate()
        {
            LastModified = DateTime.Now;
            ISession session = DBUtil.GetSession().SessionFactory.OpenSession();
            using (session.BeginTransaction())
            {
                Disjunction disj = Restrictions.Disjunction();
                if (TmdbID != 0)
                {
                    disj.Add(Restrictions.Eq("TmdbID", TmdbID));
                }
                if (IMDBID != null && IMDBID.Length > 0)
                {
                    disj.Add(Restrictions.Eq("IMDBID", IMDBID));
                }
                if (TvdbID != 0)
                {
                    disj.Add(Restrictions.Eq("TvdbID", TvdbID));
                }
                var dbVE = session.CreateCriteria(typeof(VideoEntity)).Add(disj).UniqueResult<VideoEntity>();
                if (dbVE != null)
                {
                    ID = dbVE.ID;
                    var MergedObject = new VideoEntity();
                    MergedObject.Adult = (bool)Util.CopyObject(Adult, dbVE.Adult, config.MergeType);
                    MergedObject.AudioBitrate = (int)Util.CopyObject(AudioBitrate, dbVE.AudioBitrate, config.MergeType);
                    MergedObject.AudioChannels =
                        (int)Util.CopyObject(AudioChannels, dbVE.AudioChannels, config.MergeType);
                    MergedObject.AudioCodec = (string)Util.CopyObject(AudioCodec, dbVE.AudioCodec, config.MergeType);
                    MergedObject.AudioCodecRaw =
                        (string)Util.CopyObject(AudioCodecRaw, dbVE.AudioCodecRaw, config.MergeType);
                    MergedObject.AudioFrequency =
                        (long)Util.CopyObject(AudioFrequency, dbVE.AudioFrequency, config.MergeType);
                    MergedObject.Budget = (string)Util.CopyObject(Budget, dbVE.Budget, config.MergeType);

                    MergedObject.Cast = MediaUtil.MergePersonList(Cast, dbVE.Cast, config.MergeType,
                                                                  config.MergeOnPersonName);
                    MergedObject.Categories =
                        (List<String>)Util.CopyObject(Categories, dbVE.Categories, config.MergeType);
                    MergedObject.Certifications =
                        MediaUtil.MergeCertifications(Certifications, dbVE.Certifications, config.MergeType);
                    MergedObject.ContentProtected =
                        (bool)Util.CopyObject(ContentProtected, dbVE.ContentProtected, config.MergeType);
                    MergedObject.Countries = (List<string>)Util.CopyObject(Countries, dbVE.Countries, config.MergeType);
                    MergedObject.Description = (string)Util.CopyObject(Description, dbVE.Description, config.MergeType);
                    MergedObject.Distributors =
                        (List<string>)Util.CopyObject(Distributors, dbVE.Distributors, config.MergeType);
                    MergedObject.Episodes = MediaUtil.MergeEpisodeList(Episodes, dbVE.Episodes, config.MergeType,
                                                                       config.MergeOnPersonName);
                    MergedObject.Filename = (string)Util.CopyObject(Filename, dbVE.Filename, config.MergeType);
                    MergedObject.Genre = (List<string>)Util.CopyObject(Genre, dbVE.Genre, config.MergeType);
                    MergedObject.Images = MediaUtil.MergeImageList(Images, dbVE.Images, config.MergeType);
                    MergedObject.Poster = MediaUtil.MergeImageEntity(Poster, dbVE.Poster, config.MergeType);
                    MergedObject.Backdrop = MediaUtil.MergeImageEntity(Backdrop, dbVE.Backdrop, config.MergeType);
                    MergedObject.IMDBID = (string)Util.CopyObject(IMDBID, dbVE.IMDBID, config.MergeType);
                    MergedObject.IsDelay = (bool)Util.CopyObject(IsDelay, dbVE.IsDelay, config.MergeType);
                    MergedObject.IsFinale = (bool)Util.CopyObject(IsFinale, dbVE.IsFinale, config.MergeType);
                    MergedObject.IsHDContent = (bool)Util.CopyObject(IsHDContent, dbVE.IsHDContent, config.MergeType);
                    MergedObject.IsLive = (bool)Util.CopyObject(IsLive, dbVE.IsLive, config.MergeType);
                    MergedObject.IsMovie = (bool)Util.CopyObject(IsMovie, dbVE.IsMovie, config.MergeType);
                    MergedObject.isPremire = (bool)Util.CopyObject(isPremire, dbVE.isPremire, config.MergeType);
                    MergedObject.IsRepeat = (bool)Util.CopyObject(IsRepeat, dbVE.IsRepeat, config.MergeType);
                    MergedObject.IsSAP = (bool)Util.CopyObject(IsSAP, dbVE.IsSAP, config.MergeType);
                    MergedObject.IsSport = (bool)Util.CopyObject(IsSport, dbVE.IsSport, config.MergeType);
                    MergedObject.isSubtitled = (bool)Util.CopyObject(isSubtitled, dbVE.isSubtitled, config.MergeType);
                    MergedObject.IsTVSeries = (bool)Util.CopyObject(IsTVSeries, dbVE.IsTVSeries, config.MergeType);
                    MergedObject.Languages = (List<string>)Util.CopyObject(Languages, dbVE.Languages, config.MergeType);
                    MergedObject.LastModified =
                        (DateTime?)Util.CopyObject(LastModified, dbVE.LastModified, config.MergeType);
                    MergedObject.Metadata = MediaUtil.MergeMetadataList(Metadata, dbVE.Metadata, config.MergeType);
                    MergedObject.MPAARating = (string)Util.CopyObject(MPAARating, dbVE.MPAARating, config.MergeType);
                    MergedObject.Name = (string)Util.CopyObject(Name, dbVE.Name, config.MergeType);
                    MergedObject.NetworkAffiliation =
                        (string)Util.CopyObject(NetworkAffiliation, dbVE.NetworkAffiliation, config.MergeType);
                    MergedObject.OriginalBroadcastTime =
                        (DateTime?)Util.CopyObject(OriginalBroadcastTime, dbVE.OriginalBroadcastTime, config.MergeType);
                    MergedObject.Overview = (string)Util.CopyObject(Overview, dbVE.Overview, config.MergeType);
                    MergedObject.ParentalRating =
                        (string)Util.CopyObject(ParentalRating, dbVE.ParentalRating, config.MergeType);
                    MergedObject.Popularity = (double)Util.CopyObject(Popularity, dbVE.Popularity, config.MergeType);
                    MergedObject.Rating = (double)Util.CopyObject(Rating, dbVE.Rating, config.MergeType);
                    MergedObject.Released = (DateTime?)Util.CopyObject(Released, dbVE.Released, config.MergeType);
                    MergedObject.Revenue = (string)Util.CopyObject(Revenue, dbVE.Revenue, config.MergeType);
                    MergedObject.RottenTomatosID =
                        (int)Util.CopyObject(RottenTomatosID, dbVE.RottenTomatosID, config.MergeType);
                    MergedObject.RunTime = (TimeSpan)Util.CopyObject(RunTime, dbVE.RunTime, config.MergeType);
                    MergedObject.Score = (double)Util.CopyObject(Score, dbVE.Score, config.MergeType);
                    MergedObject.SeriesAirsDaysOfWeek = MediaUtil.MergeListDayOfWeek(SeriesAirsDaysOfWeek,
                                                                                     dbVE.SeriesAirsDaysOfWeek,
                                                                                     config.MergeType);
                    MergedObject.SeriesAirsTime =
                        (DateTime?)Util.CopyObject(SeriesAirsTime, dbVE.SeriesAirsTime, config.MergeType);
                    MergedObject.SeriesID = (int)Util.CopyObject(SeriesID, dbVE.SeriesID, config.MergeType);
                    MergedObject.StationName = (string)Util.CopyObject(StationName, dbVE.StationName, config.MergeType);
                    MergedObject.Studios = (IList<string>)Util.CopyObject(Studios, dbVE.Studios, config.MergeType);
                    MergedObject.Subtitle = (string)Util.CopyObject(Subtitle, dbVE.Subtitle, config.MergeType);
                    MergedObject.TmdbID = (int)Util.CopyObject(TmdbID, dbVE.TmdbID, config.MergeType);
                    MergedObject.Trailer = (string)Util.CopyObject(Trailer, dbVE.Trailer, config.MergeType);
                    MergedObject.Translated = (bool)Util.CopyObject(Translated, dbVE.Translated, config.MergeType);
                    MergedObject.TvdbID = (int)Util.CopyObject(TvdbID, dbVE.TvdbID, config.MergeType);
                    MergedObject.URL = (string)Util.CopyObject(URL, dbVE.URL, config.MergeType);
                    MergedObject.VideoAspect = (string)Util.CopyObject(VideoAspect, dbVE.VideoAspect, config.MergeType);
                    MergedObject.VideoBitrate =
                        (float)Util.CopyObject(VideoBitrate, dbVE.VideoBitrate, config.MergeType);
                    MergedObject.VideoBitRateMode =
                        (string)Util.CopyObject(VideoBitRateMode, dbVE.VideoBitRateMode, config.MergeType);
                    MergedObject.VideoCodec = (string)Util.CopyObject(VideoCodec, dbVE.VideoCodec, config.MergeType);
                    MergedObject.VideoCodecVersion =
                        (string)Util.CopyObject(VideoCodecVersion, dbVE.VideoCodecVersion, config.MergeType);
                    MergedObject.FileSize = (long)Util.CopyObject(FileSize, dbVE.FileSize, config.MergeType);
                    MergedObject.VideoFrameRate =
                        (float)Util.CopyObject(VideoFrameRate, dbVE.VideoFrameRate, config.MergeType);
                    MergedObject.VideoHeight = (int)Util.CopyObject(VideoHeight, dbVE.VideoHeight, config.MergeType);
                    MergedObject.VideoLength =
                        (TimeSpan)Util.CopyObject(VideoLength, dbVE.VideoLength, config.MergeType);
                    MergedObject.VideoQuality =
                        (string)Util.CopyObject(VideoQuality, dbVE.VideoQuality, config.MergeType);
                    MergedObject.VideoWidth = (int)Util.CopyObject(VideoWidth, dbVE.VideoWidth, config.MergeType);
                }
            }
            session.Close();
            base.SaveOrUpdate();
        }
    }
}